package com.aube.video;

import android.content.Context;

import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.aube.model.MessageModel;
import com.huyn.baseframework.model.BaseModel;
import com.huyn.baseframework.net.BFJSONRequest;
import com.huyn.baseframework.net.HttpRequestLoader;
import com.huyn.baseframework.net.OpenApi;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;

/**
 * Created by huyaonan on 16/5/24.
 */
public class MessageHelper {

    private static final String TAG = MessageHelper.class.getSimpleName();
    private Context mContext;
    private static MessageHelper mInstance;
    private IMessageDispatcher listener;
    private String videoId;

    private MessageHelper(Context context, String videoId, IMessageDispatcher listener) {
        this.mContext = context;
        this.listener = listener;
        this.videoId = videoId;
    }

    public static synchronized MessageHelper getInstance(Context context, String videoId, IMessageDispatcher listener) {
        if(mInstance == null)
            mInstance = new MessageHelper(context, videoId, listener);
        return mInstance;
    }

    public static class Point {
        private int start, end;
        public Point(int start, int end) {
            this.start = start;
            this.end = end;
        }
        public void update(int end) {
            this.end = end;
        }
    }

    private Comparator<Point> mComparator = new Comparator<Point>() {
        @Override
        public int compare(Point lhs, Point rhs) {
            if(lhs.start < rhs.start)
                return 1;
            else if(lhs.start > rhs.start)
                return -1;
            else
                return 0;
        }
    };

    private int mNextStarttime=-1;
    private List<Point> mSectionMaps = new ArrayList<>();
    public Point getDuration(int current) {
        Point mTarget= null;

        int start = -1;
        for(Point point : mSectionMaps) {
            if(start == -1) {
                if(point.start > current) {
                    mTarget = new Point(current, point.start);
                    return mTarget;
                } else if(point.end < current) {
                    start = current;
                } else {
                    start = point.end;
                }
            } else {
                mTarget = new Point(start, point.start);
                return mTarget;
            }
        }

        return new Point(start, -1);
    }

    private static final int PRELOAD_DURATION = 20*1000;
    public boolean addDuration(Point p) {
        if(p.start >= p.end)
            return false;
        if(mSectionMaps == null || mSectionMaps.size() == 0) {
            mSectionMaps.add(p);
            mNextStarttime = p.end-PRELOAD_DURATION;
            return true;
        }
        int location=0;
        for(Point point : mSectionMaps) {
            if(p.end < point.start) {
                //insert
                mSectionMaps.add(location, p);
                mNextStarttime = p.end-PRELOAD_DURATION;
                return true;
            } else if(p.start > point.end) {
                //continue
            } else {
                int end = point.end > p.end ? point.end : p.end;
                point.end = end;
                mNextStarttime = end-PRELOAD_DURATION;
                return false;
            }
            location++;
        }
        mSectionMaps.add(p);
        mNextStarttime = p.end-PRELOAD_DURATION;
        return true;
    }

    public int getNextStarttime() {
        return mNextStarttime;
    }

    public void manageProgress(long current) {
        if(mNextStarttime <= 0)
            return;
        if(current >= mNextStarttime) {
            mNextStarttime = -1;
            fetchMessage((int) current);
        }
    }

    public void fetchMessage(int startTime) {
        if(mContext == null) {
            return;
        }
        final Point duration = getDuration(startTime);
        HashMap<String, String> parameterMap = new HashMap<>();
        parameterMap.put(OpenApi.API_METHOD, OpenApi.MESSAGE_LIST);
        parameterMap.put("maxnum", "200");
        parameterMap.put("videoid", videoId);
        parameterMap.put("startTime", duration.start+"");
        if(duration.end > 0)
            parameterMap.put("endTime", duration.end+"");
        BFJSONRequest request = new BFJSONRequest(MessageModel.class, parameterMap, new Response.Listener<MessageModel>() {

            @Override
            public void onResponse(MessageModel response) {
                if(response.success()) {
                    duration.update(response.getEndTime());
                    if(listener != null && addDuration(duration))
                        listener.dispatchResponse(response);
                } else {
                }
            }

            @Override
            public void onErrorResponse(VolleyError error) {
            }

            @Override
            public void onStart() {
            }
        });
        request.setTag(TAG);
        HttpRequestLoader.getInstance(mContext).startCacheLoader("", request, true);
    }

    public void sendMessage(String msg, String videoId, int videoTime) {
        if(mContext == null) {
            return;
        }
        HashMap<String, String> parameterMap = new HashMap<>();
        parameterMap.put(OpenApi.API_METHOD, OpenApi.MESSAGE_SEND);
        parameterMap.put("content", msg);
        parameterMap.put("videoid", videoId);
        parameterMap.put("videoTime", videoTime+"");
        BFJSONRequest request = new BFJSONRequest(BaseModel.class, parameterMap, new Response.Listener<BaseModel>() {

            @Override
            public void onResponse(BaseModel response) {
                if(response.success()) {
                } else {
                }
            }

            @Override
            public void onErrorResponse(VolleyError error) {
            }

            @Override
            public void onStart() {
            }
        });
        request.setTag(TAG);
        HttpRequestLoader.getInstance(mContext).startCacheLoader("", request, true);
    }

    public void onDestroy() {
        videoId = null;
        listener = null;
        mInstance = null;
    }

    public interface IMessageDispatcher {
        public void dispatchResponse(MessageModel model);
    }

}
